package com.cn.common;

import com.cn.remote.InvokeCallback;
import com.cn.remote.SeamphoreOneWayImpl;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

public class ResponseFuture2 {

    private final long timeoutMillis;
    private final long beginTimestamp = System.currentTimeMillis();
    private final CountDownLatch countDownLatch = new CountDownLatch(1);
    private byte[] body;
    //异步模式回调
    private InvokeCallback invokeCallback;
    private SeamphoreOneWayImpl seamphoreOneWay;

    public ResponseFuture2(long timeoutMillis) {
        this.timeoutMillis = timeoutMillis;
    }

    public ResponseFuture2(long timeoutMillis, InvokeCallback invokeCallback) {
        this.timeoutMillis = timeoutMillis;
        this.invokeCallback = invokeCallback;
    }

    public ResponseFuture2(long timeoutMillis, InvokeCallback invokeCallback, SeamphoreOneWayImpl seamphoreOneWay) {
        this.timeoutMillis = timeoutMillis;
        this.invokeCallback = invokeCallback;
        this.seamphoreOneWay = seamphoreOneWay;
    }

    public void putResponse(byte[] body) {
        this.body = body;
        this.countDownLatch.countDown();
    }

    public void executInvokeCallback() {
        if (this.invokeCallback != null) {
            this.invokeCallback.callback(this.body);
        }
    }

    public void release() {
        if (this.seamphoreOneWay != null) {
            this.seamphoreOneWay.release();
        }
    }

    public byte[] await(long timeout) {
        try {
            this.countDownLatch.await(timeout, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return this.body;
    }

    public InvokeCallback getInvokeCallback() {
        return invokeCallback;
    }

    public void setInvokeCallback(InvokeCallback invokeCallback) {
        this.invokeCallback = invokeCallback;
    }

    public byte[] getBody() {
        return body;
    }
}
